home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / misc / emu / x128utils.lha / Sources / DAT2SLT.C next >
Encoding:
C/C++ Source or Header  |  2002-08-25  |  10.7 KB  |  537 lines

  1. /******************************************/
  2. /**                                      **/
  3. /**         DAT2SLT.C DAT Combiner       **/
  4. /**                                      **/
  5. /**          (C) James McKay 1996        **/
  6. /**                                      **/
  7. /**    This software may not be used     **/
  8. /**    for commercial reasons, the code  **/
  9. /**    may not be modified or reused     **/
  10. /**    without permission.               **/
  11. /**                                      **/
  12. /******************************************/
  13.  
  14. #define SEEK_SET 0
  15. #define SEEK_CUR 1
  16. #define SEEK_END 2
  17.  
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <ctype.h>
  22.  
  23. /* It is essential that a word is 16 bits wide and a char is 8 bits wide */
  24.  
  25. /* A quick fix for Borland */
  26. #ifdef __BORLANDC__
  27. #define word unsigned int
  28. #else
  29. #define word unsigned short
  30. #endif
  31.  
  32. #define UC unsigned char
  33.  
  34. #define MAXPATH 300
  35.  
  36. char input_name[MAXPATH];
  37. char output_name[MAXPATH];
  38. char param4[MAXPATH];
  39.  
  40. char *ID_String="SLT";
  41. char *ID_000="\0\0\0";
  42. char *End_Of_Table="\0\0\0\0\0\0\0\0";
  43.  
  44. char *in_buffer, *out_buffer;
  45.  
  46. long DAT_offset[256];
  47. long SLT_lscr_offset;
  48.  
  49. FILE *output_handle;
  50.  
  51. UC acorn_form=0;
  52.  
  53. /* Set this to 1 for default if compiling under DOS */
  54. UC dos_form=1;
  55.  
  56. void clean_buffers(void)
  57. {
  58.     memset(in_buffer,0,0xFFFF);
  59.     memset(out_buffer,0,0xFFFF);
  60. }
  61.  
  62. void lower_it(char *stringy)
  63. {
  64.     int pos, x;
  65.  
  66.     pos=strlen(stringy);
  67.     for(x=0;x<pos;x++)
  68.     {
  69.         stringy[x]=tolower(stringy[x]);
  70.     }
  71. }
  72.  
  73. void strip_extension(char *stringy)
  74. {
  75.     int pos;
  76.  
  77.     pos=strlen(stringy);
  78.     pos--;
  79.     while((stringy[pos]!='.')&&(pos)&&
  80.     (stringy[pos]!='\\')&&(stringy[pos]!='/')) pos--;
  81.  
  82.     if(stringy[pos]=='.') stringy[pos]='\0'; /* If ext, then cut */
  83. }
  84.  
  85. int get_length_of_pre(char *stringy)
  86. {
  87. /* Assumes that extension has already been stripped and that there is no
  88.  / or \ at the end of this string */
  89.     int pos, pre_len;
  90.  
  91.     if(acorn_form) return 0;
  92.     pos=strlen(stringy);
  93.     pos--;
  94.     pre_len=0;
  95.     while((stringy[pos]!='/')&&(stringy[pos]!='\\')&&(pos>=0))
  96.     {
  97.         pre_len++;
  98.         pos--;
  99.     }
  100.     return pre_len;
  101. }
  102.  
  103. void itoa_temp(char *stringy, UC x)
  104. {
  105.     char *original_point;
  106.     UC temp;
  107.  
  108.     original_point=stringy;
  109.     temp=0;
  110.     if(x>=100)
  111.     {
  112.         temp=0;
  113.         while(x>=100)
  114.         {
  115.             x-=100;
  116.             temp++;
  117.         }
  118.         *stringy++=temp+'0';
  119.     }
  120.     if(x>=10)
  121.     {
  122.         temp=0;
  123.         while(x>=10)
  124.         {
  125.             x-=10;
  126.             temp++;
  127.         }
  128.         *stringy++=temp+'0';
  129.     }
  130.     else
  131.     {
  132.         if(temp) /* 100's but not 10's */
  133.         {
  134.             *stringy++='0';
  135.         }
  136.     }
  137.     *stringy++=x+'0';
  138.     *stringy='\0';
  139.     stringy=original_point;
  140. }
  141.  
  142. void add_level_num(char *stringy, UC number)
  143. {
  144.     char num_str[4];
  145.     int pre_len, pos;
  146.  
  147.     itoa_temp((char *)num_str,number);
  148.     pre_len=get_length_of_pre(stringy);
  149.     if((dos_form)&&((pre_len+strlen(num_str))>8))
  150.     {
  151.         /* Snippy bits for DOS */
  152.         pos=strlen(stringy);
  153.         stringy[pos-strlen(num_str)]='\0';
  154.     }
  155.     strcat(stringy,num_str);
  156. }
  157.  
  158. void compress_DAT(long table_offset, word total_length)
  159. {
  160.     word in_index, out_index, xx;
  161.     UC yy, special, single_ED, out_lo, out_hi, zero;
  162.     long temp_ftell;
  163.  
  164.     out_index=single_ED=in_index=0;
  165.     while(in_index<total_length)
  166.     {
  167.         yy=in_buffer[in_index];
  168.         special=0;
  169.         xx=1;
  170.         while((xx<256)&&(!special))
  171.         {
  172.             if(in_index+xx<total_length)
  173.             {
  174.                 if(in_buffer[in_index+xx]==yy)
  175.                 {
  176.                     xx++;
  177.                 }
  178.                 else
  179.                 {
  180.                     special=1;
  181.                 }
  182.                 if(xx==255) special=1;
  183.             }
  184.             else
  185.             {
  186.                 /* Leave loop, reached the end */
  187.                 special=1;
  188.             }
  189.  
  190.         }
  191.         if(((xx>=2)&&(yy==0xED))||(xx>=5))
  192.         {
  193.             if(single_ED)
  194.             {
  195.                 out_buffer[out_index++]=yy;
  196.                 out_buffer[out_index++]=0xED;
  197.                 out_buffer[out_index++]=0xED;
  198.                 out_buffer[out_index++]=xx-1;
  199.                 out_buffer[out_index++]=yy;
  200.             }
  201.             else
  202.             {
  203.                 out_buffer[out_index++]=0xED;
  204.                 out_buffer[out_index++]=0xED;
  205.                 out_buffer[out_index++]=xx;
  206.                 out_buffer[out_index++]=yy;
  207.             }
  208.             in_index+=xx;
  209.             single_ED=0;
  210.         }
  211.         else
  212.         {
  213.             out_buffer[out_index++]=yy;
  214.             in_index++;
  215.             if(yy==0xED)
  216.             {
  217.                 single_ED=1;
  218.             }
  219.             else
  220.             {
  221.                 single_ED=0;
  222.             }
  223.         }
  224.     }
  225.     out_lo=out_index&0xFF;
  226.     out_hi=(out_index&0xFF00)>>8;
  227.     temp_ftell=ftell(output_handle);
  228.  
  229.     fseek(output_handle,table_offset,SEEK_SET); /* back to table */
  230.     fwrite(&out_lo,1,1,output_handle);
  231.     fwrite(&out_hi,1,1,output_handle);
  232.     zero=0;
  233.     fwrite(&zero,1,1,output_handle);
  234.     fwrite(&zero,1,1,output_handle);
  235.     fseek(output_handle,temp_ftell,SEEK_SET); /* back to end */
  236.     fwrite(out_buffer,1,out_index,output_handle);
  237. }
  238.  
  239. void construct_SCR_table(void)
  240. {
  241.     char temp_str[MAXPATH];
  242.     char temp_str2[MAXPATH];
  243.  
  244.     FILE *temp_handle;
  245.     UC temp_char;
  246.  
  247.     strcpy(temp_str,input_name);
  248.     strcpy(temp_str2,input_name);
  249.     strcat(temp_str,".SCR");
  250.     strcat(temp_str2,".scr");
  251.     if(!(temp_handle = fopen(temp_str,"rb")))
  252.     {
  253.         if(!(temp_handle = fopen(temp_str2,"rb")))
  254.         {
  255.             return;
  256.         }
  257.     }
  258.  
  259.     temp_char=3; /* Signify type is loading screen */
  260.     fwrite(&temp_char,1,1,output_handle);
  261.     temp_char=0;
  262.     fwrite(&temp_char,1,1,output_handle);
  263.  
  264.     temp_char=0; /* Write level number */
  265.     fwrite(&temp_char,1,1,output_handle);
  266.     temp_char=0;
  267.     fwrite(&temp_char,1,1,output_handle);
  268.  
  269.     SLT_lscr_offset=ftell(output_handle); /* later for length */
  270.     fwrite(&temp_char,1,1,output_handle); /* Write null length */
  271.     fwrite(&temp_char,1,1,output_handle); /* for the moment */
  272.     fwrite(&temp_char,1,1,output_handle);
  273.     fwrite(&temp_char,1,1,output_handle);
  274.  
  275.     fclose(temp_handle);
  276. }
  277.  
  278. void construct_DAT_table(UC level_num)
  279. {
  280.     char temp_str[MAXPATH];
  281.     char temp_str2[MAXPATH];
  282.  
  283.     FILE *temp_handle;
  284.     UC temp_char;
  285.  
  286.     if(acorn_form)
  287.     {
  288.         strcpy(temp_str,"");
  289.         strcpy(temp_str2,"");
  290.     }
  291.     else
  292.     {
  293.         strcpy(temp_str,input_name);
  294.         strcpy(temp_str2,input_name);
  295.     }
  296.     add_level_num((char *)temp_str,level_num);
  297.     add_level_num((char *)temp_str2,level_num);
  298.     strcat(temp_str,".DAT");
  299.     if(!acorn_form) strcat(temp_str2,".dat");
  300.     if(!(temp_handle = fopen(temp_str,"rb")))
  301.     {
  302.         if(!(temp_handle = fopen(temp_str2,"rb")))
  303.         {
  304.             return;
  305.         }
  306.     }
  307.  
  308.     temp_char=1; /* Signify type is level data */
  309.     fwrite(&temp_char,1,1,output_handle);
  310.     temp_char=0;
  311.     fwrite(&temp_char,1,1,output_handle);
  312.  
  313.     temp_char=level_num; /* Write level number */
  314.     fwrite(&temp_char,1,1,output_handle);
  315.     temp_char=0;
  316.     fwrite(&temp_char,1,1,output_handle);
  317.  
  318.     DAT_offset[level_num]=ftell(output_handle); /* later for length */
  319.     fwrite(&temp_char,1,1,output_handle); /* Write null length */
  320.     fwrite(&temp_char,1,1,output_handle); /* for the moment */
  321.     fwrite(&temp_char,1,1,output_handle);
  322.     fwrite(&temp_char,1,1,output_handle);
  323.  
  324.     fclose(temp_handle);
  325. }
  326.  
  327. void append_SCR(void)
  328. {
  329.     char temp_str[MAXPATH];
  330.     char temp_str2[MAXPATH];
  331.  
  332.     FILE *temp_handle;
  333.     long temp_long;
  334.  
  335.     strcpy(temp_str,input_name);
  336.     strcpy(temp_str2,input_name);
  337.     strcat(temp_str,".SCR");
  338.     strcat(temp_str2,".scr");
  339.     if(!(temp_handle = fopen(temp_str,"rb")))
  340.     {
  341.         if(!(temp_handle = fopen(temp_str2,"rb")))
  342.         {
  343.             return;
  344.         }
  345.     }
  346.     fseek(temp_handle,0,SEEK_END);
  347.     temp_long=ftell(temp_handle);
  348.     fseek(temp_handle,0,SEEK_SET);
  349.     clean_buffers();
  350.     fread(in_buffer,1,(word)temp_long,temp_handle);
  351.     compress_DAT(SLT_lscr_offset,(word)temp_long);
  352.     fclose(temp_handle);
  353. }
  354.  
  355. void append_DAT(UC level_num)
  356. {
  357.     char temp_str[MAXPATH];
  358.     char temp_str2[MAXPATH];
  359.  
  360.     FILE *temp_handle;
  361.     long temp_long;
  362.  
  363.     if(acorn_form)
  364.     {
  365.         strcpy(temp_str,"");
  366.         strcpy(temp_str2,"");
  367.     }
  368.     else
  369.     {
  370.         strcpy(temp_str,input_name);
  371.         strcpy(temp_str2,input_name);
  372.     }
  373.     add_level_num((char *)temp_str,level_num);
  374.     add_level_num((char *)temp_str2,level_num);
  375.     strcat(temp_str,".DAT");
  376.     if(!acorn_form) strcat(temp_str2,".dat");
  377.     if(!(temp_handle = fopen(temp_str,"rb")))
  378.     {
  379.         if(!(temp_handle = fopen(temp_str2,"rb")))
  380.         {
  381.             return;
  382.         }
  383.     }
  384.     fseek(temp_handle,0,SEEK_END);
  385.     temp_long=ftell(temp_handle);
  386.     fseek(temp_handle,0,SEEK_SET);
  387.     clean_buffers();
  388.     fread(in_buffer,1,(word)temp_long,temp_handle);
  389.     compress_DAT(DAT_offset[level_num],(word)temp_long);
  390.     fclose(temp_handle);
  391. }
  392.  
  393. void process_and_copy_z80(void)
  394. {
  395.     char temp_str[MAXPATH];
  396.     char temp_str2[MAXPATH];
  397.  
  398.     FILE *temp_handle;
  399.     long temp_long;
  400.  
  401.     strcpy(temp_str,input_name);
  402.     strcpy(temp_str2,input_name);
  403.     strcat(temp_str,".Z80");
  404.     strcat(temp_str2,".z80");
  405.  
  406.     if(!(temp_handle = fopen(temp_str,"rb")))
  407.     {
  408.         if(!(temp_handle = fopen(temp_str2,"rb")))
  409.         {
  410.             printf("Could not open input file %s\n",temp_str);
  411.             printf("Or %s\n",temp_str2);
  412.             fclose(output_handle);
  413.             exit(1);
  414.         }
  415.     }
  416.     fseek(temp_handle,0,SEEK_END);
  417.     temp_long=ftell(temp_handle);
  418.     fseek(temp_handle,0,SEEK_SET);
  419.     while(temp_long>32767)
  420.     {
  421.         fread(in_buffer,1,32768,temp_handle);
  422.         fwrite(in_buffer,1,32768,output_handle);
  423.         temp_long-=32768;
  424.     }
  425.     if(temp_long>0)
  426.     {
  427.         fread(in_buffer,1,(word)temp_long,temp_handle);
  428.         fwrite(in_buffer,1,(word)temp_long,output_handle);
  429.     }
  430.     fclose(temp_handle);
  431. }
  432.  
  433. void main(int argc, char *argv[])
  434. {
  435.     char temp_str[MAXPATH];
  436.     int x;
  437.  
  438.     printf("DAT2SLT DAT combiner by James McKay\n");
  439.     printf("Amiga port by Wojciech Pasiecznik/Voy/SSG/Dial (voydial@wp.pl) [250802]\n");
  440.     if(argc==1)
  441.     {
  442.         printf("\nThis utility combines the Z80 and it's DATs ");
  443.         printf("into one big SLT file\nand loading SCR.\n");
  444.         printf("\nUsage: DAT2SLT <input.z80> <output.slt> [/dos");
  445.         printf(" | /acorn]\n");
  446.         printf("/dos forces MS-DOS style filenames.\n");
  447.         printf("/acorn makes utility look for a file that just has");
  448.         printf(" the number as the name.\n");
  449.         exit(1);
  450.     }
  451.     if(argc<3)
  452.     {
  453.         printf("Must have input filename and output filename\n");
  454.         exit(1);
  455.     }
  456.     strcpy(input_name,argv[1]);
  457.     strcpy(output_name,argv[2]);
  458.     strip_extension((char *)input_name);
  459.     strip_extension((char *)output_name);
  460.     if(argc==4)
  461.     {
  462.         strcpy(param4,argv[3]);
  463.         if(param4[0]=='-') param4[0]='/';
  464.         lower_it((char *)param4);
  465.         if(!strcmp("/dos",param4))
  466.         {
  467.             dos_form=1;
  468.             printf("Using 8 letter format\n");
  469.         }
  470.         else
  471.         {
  472.             if(!strcmp("/acorn",param4))
  473.             {
  474.                 acorn_form=1;
  475.                 printf("Using Acorn 'no name' format.\n");
  476.             }
  477.             else
  478.             {
  479.                 printf("Last parameter can only be /dos");
  480.                 printf(" or /acorn\n");
  481.                 exit(1);
  482.             }
  483.         }
  484.     }
  485.     if(!(in_buffer=(UC *)malloc(0xFFFF)))
  486.     {
  487.           printf("Could not allocate input 64K memory buffer!\n");
  488.           exit(1);
  489.     }
  490.     else
  491.     {
  492.           memset(in_buffer,0,0xFFFF);
  493.     }
  494.     if(!(out_buffer=(UC *)malloc(0xFFFF)))
  495.     {
  496.           printf("Could not allocate output 64K memory buffer!\n");
  497.           free(in_buffer);
  498.           exit(1);
  499.     }
  500.     else
  501.     {
  502.           memset(out_buffer,0,0xFFFF);
  503.     }
  504.     strcpy(temp_str,output_name);
  505.     strcat(temp_str,".slt");
  506.     if(!(output_handle = fopen(temp_str,"w+b")))
  507.     {
  508.         perror("Error:");
  509.         printf("\nCould not open output file %s.\n",temp_str);
  510.         free(in_buffer);
  511.         free(out_buffer);
  512.         exit(1);
  513.     }
  514.     process_and_copy_z80();
  515.     fwrite(ID_000,1,3,output_handle);
  516.     fwrite(ID_String,1,strlen(ID_String),output_handle);
  517.     for(x=0;x<256;x++)
  518.     {
  519.         construct_DAT_table(x);
  520.     }
  521.     /* Construct Instructions */
  522.     construct_SCR_table();
  523.     /* Construct Scanned Pictures !!! */
  524.     /* Construct Pokes */
  525.     fwrite(End_Of_Table,1,8,output_handle);
  526.     for(x=0;x<256;x++)
  527.     {
  528.         append_DAT(x);
  529.     }
  530.     /* Append Instructions.txt */
  531.     append_SCR();
  532.     /* Append Scanned Pictures!!! */
  533.     /* Append Pokes */
  534.     fclose(output_handle);
  535.     free(in_buffer);
  536.     free(out_buffer);
  537. }